package com.ece400.abrc;

import android.R.string;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.ImageView.ScaleType;
import com.ece400.abrc.*;

public final class Dpad extends LinearLayout{

	private static ImageView img_cursor;
	//the dead space is the width on the controller where the robot only moves forwards/backwards tor pivots
	private float dead_space = 60;
	private float dpad_size;
	private float cursor_size;
	private float y_dead_t, y_dead_b, x_dead_l, x_dead_r;
	private static float x_cursor_l;
	private static float y_cursor_t;
	private boolean bll_have_dims;
	
	/*
	Turn fractions dictate how much the robot turns when the user hits a corner of the controller.
	To turn, the two tracks move at different speeds.
	track1_speed = track2_speed * turn_fraction
	Therefore, a turn fraction of 1 gives no turning
	A turn fraction of 0 gives pivoting.
	The start and ending turn fractions can be adjusted to alter the steering radius.
	*/
	private static float turn_frac_start = (float).1;
	private static float turn_frac_end = (float) 0;
	
	public Dpad(Context context, AttributeSet attrs) {
		super(context, attrs);
		
		bll_have_dims = false;
		LayoutInflater layoutInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
		View view_dpad = layoutInflater.inflate(R.layout.dpad,this);
		
		img_cursor = (ImageView) view_dpad.findViewById(R.id.img_cursor);
		
		//txt_x = (TextView) view_main.findViewById(R.id.txt_view_x);
		//txt_y = (TextView) view_dpad.findViewById(R.id.txt_view_y);
		
		Log.d("constructor done","constructor done");
	}
	
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		
		//background image is touched
		
		int action = event.getAction();
		float x,y;
		boolean touching;
		
		x = 0;
		y = 0;
		
		switch(action){
		case MotionEvent.ACTION_MOVE:
			x = event.getX();
			y = event.getY();
			touching = true;
			break;
		case MotionEvent.ACTION_DOWN:
			x = event.getX();
			y = event.getY();
			touching = true;
			break;
		case MotionEvent.ACTION_UP:
			touching = false;
			break;
		default:
			touching = false;
			break;
		}
		
		if(touching == true){
			cursor_update_full_control(x,y);
		}else{
			//reset the cursor
			cursor_reset();
		}
		
		return true;

	}
	
	private enum ControlCell{
		TL, T, TR, L, C, R, BL, B, BR
	}
	
	private void cursor_update_full_control(float x,float y) {
		
		RelativeLayout.LayoutParams lp;
		int i_new_margin_t, i_new_margin_l;
		boolean bll_outside;
		ControlCell cell;
		float speed_l, speed_r; //our calculation goal, track speeds -1 to 1
		float turn_frac;
		
		/*
		The control square is split into 9 cells.
		The middle cell is a dead space.
		The other 8 cells have different behaviors.
		The corners mix X and Y. The other 4 (T,L,R,B) either pivot, or move forwards/backwards.
		The size of T,L,R,B is controlled by the variable dead_space.
		______________
		| TL | T| TR |
		|____|  |____|
		|__L_  C _R__|
		|  BL| B| BR |
		|____|__|____|
		*/
		
		//check if we moved outside of the control box
		//if we did, we limit the x,y
		//but we adjust the cursor to the outermost edge
		bll_outside = false;
		
		if(x<0+cursor_size/2){
			//too far left
			bll_outside = true;
			x = cursor_size/2;
		}else if(x>dpad_size-cursor_size/2){
			//too far right
			bll_outside = true;
			x = dpad_size-cursor_size/2;
		}
		if(y < 0+cursor_size/2){
			//too far up
			bll_outside = true;
			y = cursor_size/2;
		}else if(y > dpad_size-cursor_size/2){
			//too far down
			bll_outside = true;
			y = dpad_size-cursor_size/2;
		}
		
		//move cursor
		i_new_margin_t = Math.round(y-(float)cursor_size/2);
		i_new_margin_l = Math.round(x-(float)cursor_size/2);
		
		lp = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
		lp.setMargins(i_new_margin_l, i_new_margin_t, 0, 0);
		img_cursor.setLayoutParams(lp);
		
		//convert x and y to be between -1 and 1
		if(y>=y_dead_t && y<=y_dead_b){
			//on the pivoting dead-space
			if(x<x_dead_l){
				//pivot left
				cell = ControlCell.L;
			}else if(x>x_dead_r){
				//pivot right
				cell = ControlCell.R;
			}else{
				//in the dead center space
				cell = ControlCell.C;
			}
		}else if(x>=x_dead_l && x<=x_dead_r){
			//on the forwards/backwards dead-space
			if(y<y_dead_t){
				cell = ControlCell.T;
			}else{
				cell = ControlCell.B;
			}
		}else{
			//on a corner
			if(x<x_dead_l){
				//left
				if(y<y_dead_t){
					//top
					cell = ControlCell.TL;
				}else{
					//bottom
					cell = ControlCell.BL;	
				}
			}else{
				//right
				if(y<y_dead_t){
					//top
					cell = ControlCell.TR;
				}else{
					//bottom
					cell = ControlCell.BR;	
				}
			}
		}
		
		//generate two floats: one for the left track and one for the right
		//these will be between -1 and 1 (full reverse to full forwards)
		speed_l = speed_r = 0;
		switch(cell){
			case T:
				//for the top and bottom cells, the left and right
				//tracks will be set to an equal speed so that they move at the same speed
				speed_l = speed_r = (y*-1+y_dead_t)/(y_dead_t-cursor_size/2);
				break;
			case B:
				speed_l = speed_r = (y_dead_b - y)/(dpad_size-cursor_size/2-y_dead_b);
				break;
			case R:
				//for the left and right pivots, the tracks have the same magnitude, but different signs
				speed_l = (x-x_dead_r)/(dpad_size-cursor_size/2-x_dead_r);
				speed_r = -1*speed_l;
				break;
			case L:
				speed_r = (x-x_dead_l)/(cursor_size/2-x_dead_l);
				speed_l = -1*speed_r;
				break;
			case TL:
				//calculate the vertical speed (same as T equation) for the right track
				speed_r = (y*-1+y_dead_t)/(y_dead_t-cursor_size/2);
				//the left track speed is a fraction of the right track speed
				//the smaller the fraction, the more it turns
				turn_frac = (turn_frac_end-turn_frac_start)/(cursor_size/2-x_dead_l)*(x-x_dead_l)+turn_frac_start;
				speed_l = speed_r * turn_frac;
				break;
			case TR:
				//calculate the vertical speed (same as T equation) for the left track
				speed_l = (y*-1+y_dead_t)/(y_dead_t-cursor_size/2);
				turn_frac = (turn_frac_end-turn_frac_start)/(dpad_size-cursor_size/2-x_dead_r)*(x-x_dead_r)+turn_frac_start;
				speed_r = speed_l * turn_frac;
				break;
			case C:
				speed_l = 0;
				speed_r = 0;
				break;
			case BL:
				//right track speed is same as B equation
				speed_r = (y_dead_b - y)/(dpad_size-cursor_size/2-y_dead_b);
				//left track speed is a fraction of right, same equation as TL fraction
				turn_frac = (turn_frac_end-turn_frac_start)/(cursor_size/2-x_dead_l)*(x-x_dead_l)+turn_frac_start;
				speed_l = speed_r * turn_frac;
				break;
			case BR:
				//left track speed same as B equation
				speed_l = (y_dead_b - y)/(dpad_size-cursor_size/2-y_dead_b);
				//same equation as TR fraction
				turn_frac = (turn_frac_end-turn_frac_start)/(dpad_size-cursor_size/2-x_dead_r)*(x-x_dead_r)+turn_frac_start;
				speed_r = speed_l * turn_frac;
				break;
		}

		Log.d("speed_l", String.valueOf(speed_l));
		Log.d("speed_r", String.valueOf(speed_r));
		
		//send movement command to the server
		RobotConnection.NewMoveCmd(speed_l,speed_r);
	}
	
	private static void cursor_reset() {
		//centers the cursor with the default size
		
		RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
		
		//margin sets number of extra pixels on the side
		//left top right bottom
		lp.setMargins((int)y_cursor_t, (int)x_cursor_l, 0, 0);
		img_cursor.setLayoutParams(lp);
		
		//stops robot from moving
		RobotConnection.NewMoveCmd(0,0);
	}
	
	@Override
	protected void onMeasure (int widthMeasureSpec, int heightMeasureSpec){
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
		
		if(bll_have_dims == false){
			//get sizes
			cursor_size = img_cursor.getWidth();
			dpad_size = this.getWidth();
			if(cursor_size != 0 && dpad_size != 0){
				bll_have_dims = true;
			}

			y_cursor_t = dpad_size/2-cursor_size/2;			
			x_cursor_l = y_cursor_t;
			y_dead_t = dpad_size/2 - dead_space/2;
			y_dead_b = dpad_size/2 + dead_space/2;
			x_dead_l = y_dead_t;
			x_dead_r = y_dead_b;
			
			Log.d("ONMEASURE ","dpad_size= " + dpad_size + " cursor_size=" + cursor_size);
		}
	}

	
}